
package org.sql.commands.mysql.command;

// *************************************************************************/
// Charada Soft
// Area de Desarrollo de Sistemas de Información
// *************************************************************************/
// Proyecto : java connector sql 
// Archivo : Select.java
// Descripcion : Clase Select
// *************************************************************************/
// Version : 2.10.4
// Fecha de Creación: 01 de Julio de 2014
// Author : Daniel Andres Castillo Pedroza
// *************************************************************************/

import java.util.ArrayList;
import org.sql.commands.Clause;
import org.sql.commands.exception.DMLException;

public class Select extends DML {
    
    // Atributos de la clase Select
    
    private ArrayList <Clause> clauses;
    private ArrayList <String> columns;
    private ArrayList <String> tables;
    private boolean isDistinct;
    
    public Select() {
      clauses = new ArrayList <> (); columns = new ArrayList <> (); tables = new ArrayList <> ();
    }
    
    // Metodos de la clase Select
    
    /**
      * 
      * @param clauses 
    */

    public void setClauses(ArrayList <Clause> clauses) {
      this.clauses = clauses;
    }
    
    /**
      * 
      * @param clause 
    */
    
    public void addClause(Clause clause) {
      clauses.add(clause);
    }
    
    /**
      * 
      * @param tables 
    */

    public void setTables(ArrayList <String> tables) {
      this.tables = tables;
    }
    
    /**
      * 
      * @param table 
    */
    
    public void addTable(String table) {
      tables.add(table);
    }
    
    /**
      * 
      * @param columns 
    */

    public void setColumns(ArrayList <String> columns) {
      this.columns = columns;
    }
    
    /**
      * 
      * @param column 
    */
    
    public void addColumn(String column) {
      columns.add(column);
    }
    
    /**
      * 
      * @param isDistinct 
    */
    
    public void setDistinct(boolean isDistinct) {
      this.isDistinct = isDistinct;
    }
    
    // Metodos estáticos de la clase Select
    
    /**
      * 
      * @param column
      * @param table
      * @return 
    */
    
    public static Select creatorCommand(String column, String table) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.addTable(table);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param table
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, String table) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.addTable(table);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param column
      * @param tables
      * @return 
    */
    
    public static Select creatorCommand(String column, ArrayList <String> tables) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.setTables(tables);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param tables
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, ArrayList <String> tables) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.setTables(tables);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param column
      * @param table
      * @param clause
      * @return 
    */
    
    public static Select creatorCommand(String column, String table, Clause clause) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.addTable(table); select.addClause(clause);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param table
      * @param clause
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, String table, Clause clause) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.addTable(table); select.addClause(clause);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param column
      * @param tables
      * @param clause
      * @return 
    */
    
    public static Select creatorCommand(String column, ArrayList <String> tables, Clause clause) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.setTables(tables); select.addClause(clause);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param column
      * @param table
      * @param clauses
      * @return 
    */
    
    public static Select creatorCommand(String column, String table, ArrayList <Clause> clauses) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.addTable(table); select.setClauses(clauses);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param tables
      * @param clause
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, ArrayList <String> tables, Clause clause) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.setTables(tables); select.addClause(clause);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param table
      * @param clauses
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, String table, ArrayList <Clause> clauses) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.addTable(table); select.setClauses(clauses);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param column
      * @param tables
      * @param clauses
      * @return 
    */
    
    public static Select creatorCommand(String column, ArrayList <String> tables, ArrayList <Clause> clauses) {
      Select select = new Select(); // Instanciando objeto
      select.addColumn(column); select.setTables(tables); select.setClauses(clauses);
      
      return select; // Retornando Objeto SELECT
    }
    
    /**
      * 
      * @param columns
      * @param tables
      * @param clauses
      * @return 
    */
    
    public static Select creatorCommand(ArrayList <String> columns, ArrayList <String> tables, ArrayList <Clause> clauses) {
      Select select = new Select(); // Instanciando objeto
      select.setColumns(columns); select.setTables(tables); select.setClauses(clauses);
      
      return select; // Retornando Objeto SELECT
    }

    // Metodos sobreescrito de la clase Select
    
    @Override
    public String getCommand() throws DMLException {
      // Declarando y configurando dato para Proceso
      String commandSelect = "SELECT"; 
      
      if (isDistinct) {
        commandSelect = commandSelect + " DISTINCT";
      } // Habilitamos DISTINCT en la Sentencia
      
      if ((columns == null) || (columns.isEmpty())) {
        throw new DMLException(DMLException.COLUMNS_UNDEFINED);
      } // No ha definido las Columnas de la Sentencia
      
      commandSelect += " " + ConfiguratorCommand.columnsForCommand(columns);
      
      if ((tables == null) || (tables.isEmpty())) {
        throw new DMLException(DMLException.TABLES_UNDEFINED);
      } // No ha definido las Columnas de la Sentencia
      
      commandSelect += " FROM " + ConfiguratorCommand.tablesForSelect(tables);
      
      if ((clauses != null) && (!clauses.isEmpty())) {
        for (Clause clause : clauses) {
          commandSelect += " " + clause.getClause();
        } // Estableciendo las clausulas del Comando
      } // Se han establecido clausulas en el Comando
      
      return commandSelect; // Retornando Comando SELECT
    }
}